package dir.simulation;

import java.util.Vector;

import dht.data.Access;
import dht.data.Message;
import dht.data.MessageType;
import dht.simulation.DhtException;
import dht.simulation.GlobalVariables;
import dht.statistics.DhtStatistics;

public class DirMasterNode {

	public int masterId;
	public Directory directory;
	public double idleTime;
	public static final double diskTime = GlobalVariables.masterDiskTime;

	public DirMasterNode(int masterId, int serverNum) {
		directory = new Directory(serverNum);
		this.idleTime = 0.0;
	}

	public Vector<Message> masterProcessMsg(Message msg, Access access)
			throws DhtException {
		DhtStatistics.serverCpuReport(0,
				Math.max(idleTime, msg.getCurrentTime()) - idleTime, diskTime,
				Math.max(idleTime, msg.getCurrentTime()) + diskTime);

		if (msg.msgType == MessageType.DIR_META_READ_ACK
				|| msg.msgType == MessageType.DIR_META_WRITE_ACK) {
			idleTime = Math.max(idleTime, msg.getCurrentTime()) + diskTime;
			return null;
		}

		Vector<Message> msgList = new Vector<Message>();
		Message newMsg = new Message();

		newMsg.accessId = msg.accessId;
		newMsg.fromId = msg.toId;
		newMsg.toId = msg.fromId;
		newMsg.generateTime = msg.getCurrentTime();

		idleTime = Math.max(idleTime, newMsg.generateTime);
		newMsg.waitingCost = idleTime - newMsg.generateTime;
		newMsg.processCost = diskTime;
		newMsg.sendTime = newMsg.generateTime + newMsg.waitingCost
				+ newMsg.processCost;
		idleTime = newMsg.sendTime;

		int fwdId = directory.lookup(access.fileName);
		switch (msg.msgType) {
		case DIR_META_READ_REQ:
			DhtStatistics.serverReport(0, 0, 0, 1, 0);
			newMsg.msgSize = GlobalVariables.readFwdSize;
			newMsg.msgType = MessageType.DIR_META_READ_RESP;
			newMsg.fwdToId = fwdId;
			break;
		case DIR_META_WRITE_REQ:
			DhtStatistics.serverReport(0, 0, 0, 0, 1);
			newMsg.msgSize = GlobalVariables.writeFwdSize;
			newMsg.msgType = MessageType.DIR_META_WRITE_RESP;
			newMsg.fwdToId = fwdId;
			break;
		case DIR_META_READ_ACK:
			return null;
		case DIR_META_WRITE_ACK:
			return null;
		default:
			throw new DhtException("masterProcessMsg msgType unknown");
		}
		msgList.add(newMsg);
		return msgList;

	}
}
